package org.shagin.jfin.ui.date.cond;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.shagin.jfin.core.Debug;
import org.shagin.jfin.date.DateUtils;
import org.shagin.jfin.date.cond.IDateCondition;
import org.shagin.jfin.date.cond.Yearly;
import org.shagin.jfin.ui.UI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class YearlyPane.
 */
@SuppressWarnings("serial")
public class JYearlyPane extends DateConditionPane<Yearly> {

    private static final Logger log = LoggerFactory
            .getLogger(JYearlyPane.class);

    private Map<Integer, JRadioButton> items = new HashMap<Integer, JRadioButton>();
    private JComboBox<Integer> cbDay = new JComboBox<Integer>();
    private ButtonGroup group = new ButtonGroup();
    private ChangeListener changeListener;
    private ActionListener actionListener;

    /**
     * Instantiates a new yearly pane.
     */
    public JYearlyPane() {
        super();
        setDateCondition(new Yearly(Calendar.JANUARY, 1));
        initView();
        initListeners();
        addListeners();
    }

    /**
     * Inits the view.
     */
    private void initView() {
        setLayout(new BorderLayout());
        JPanel panelNorth = new JPanel(new FlowLayout(FlowLayout.LEFT, UI.HGAP,
                UI.VGAP));
        panelNorth.add(cbDay);
        for (int i = 1; i < 32; i++) {
            cbDay.addItem(i);
        }
        add(panelNorth, BorderLayout.NORTH);

        JPanel panel = new JPanel(new GridLayout(4, 3));

        for (int i = Calendar.JANUARY; i < Calendar.UNDECIMBER; i++) {
            JRadioButton item = new JRadioButton(DateUtils.getMonth(i) + " ( "
                    + (i + 1) + " )");
            group.add(item);
            panel.add(item);
            items.put(i, item);
        }
        add(panel, BorderLayout.CENTER);
    }

    /**
     * Gets the day.
     * 
     * @return the day
     */
    private int getDay() {
        return cbDay.getSelectedIndex() + 1;
    }

    /**
     * Sets the day.
     * 
     * @param day the new day
     */
    private void setDay(int day) {
        cbDay.setSelectedItem(new Integer(day));
    }

    /**
     * Gets the month.
     * 
     * @return the month
     */
    private int getMonth() {
        int result = -1;
        for (Map.Entry<Integer, JRadioButton> entry : items.entrySet()) {
            if (entry.getValue().isSelected()) {
                result = entry.getKey().intValue();
                break;
            };
        }
        return result;
    }

    /**
     * Sets the month.
     * 
     * @param month the new month
     */
    private void setMonth(int month) {
        Debug.traceEnter(log, month);
        group.clearSelection();
        for (Map.Entry<Integer, JRadioButton> entry : items.entrySet()) {
            if (entry.getKey().intValue() == month) {
                entry.getValue().setSelected(true);
                break;
            };
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Yearly getValue() {
        return (Yearly) dateCondition;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getTitle() {
        // TODO Localize
        return "Каждый год";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setDateCondition(IDateCondition dateCondition) {
        Debug.traceEnter(log);
        removeListeners();
        super.setDateCondition(dateCondition);
        setDay(getValue().getDay());
        setMonth(getValue().getMonth());
        addListeners();
    }

    /**
     * Adds the listeners.
     */
    private void addListeners() {
        for (Map.Entry<Integer, JRadioButton> entry : items.entrySet()) {
            entry.getValue().addChangeListener(changeListener);
        }
        cbDay.addActionListener(actionListener);
    }

    private void initListeners() {
        actionListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Debug.traceEnter(log);
                fireChangedEvent();
            }
        };

        changeListener = new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                Debug.traceEnter(log);
                fireChangedEvent();
            }
        };
    }

    /**
     * Removes the listeners.
     */
    private void removeListeners() {
        cbDay.removeActionListener(actionListener);
        for (Map.Entry<Integer, JRadioButton> entry : items.entrySet()) {
            entry.getValue().removeChangeListener(changeListener);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void fireChangedEvent() {
        getValue().setDay(getDay());
        getValue().setMonth(getMonth());
        super.fireChangedEvent();
    }

}
